package fr.cephb.joperon.core.iterator;

import java.util.Iterator;

import fr.cephb.util.CloseableIterator;

/** basic implementation of a delegate Iterator
 * iterating over another iterator and extracting a componenent from it
 * @author lindenb
 *
 * @param <I> IN : the delegate iterator type
 * @param <O> OUT : the type returned by this iterator
 */
public  abstract class DelegateIterator<I,O>
extends AbstractIterator<O>
	{
	private Iterator<I> delegate;
	/**
	 * Construct this iterator with its delegate iterator
	 * @param delegate the input iterator
	 */
	public DelegateIterator(Iterator<I> delegate)
		{
		this.delegate=delegate;
		}
	/** get the delegate iterator */
	public Iterator<I> getDelegate() {
		return delegate;
		}
	
	@Override
	public boolean hasNext() {
		return getDelegate().hasNext();
		}
	
	@Override
	/** calls extractValue(getDelegate().next()) */
	public O next() {
		return extractValue(getDelegate().next());
		}
	
	@Override
	public void remove() {
		getDelegate().remove();
		}
	@Override
	/** close this and the delegate iterator if it is a CloseableIterator */
	public void close()
		{
		if(getDelegate() instanceof CloseableIterator)
			{
			CloseableIterator.class.cast(getDelegate()).close();
			}
		super.close();
		}
	/** extract the ouput(OUT) value from a delegate(IN) value */
	protected abstract O extractValue(I input);
	}
